/**
 * 渠道发布
 * releaseStatus 渠道发布状态（0=未发布 1=已发布 2=待审核 3=已下线）
 *
 */
import React from 'react';
import { Card, Button, Row, Col, Checkbox, Collapse, Typography, message, Modal, Empty } from 'antd';
import { history } from 'umi'
import { useRequest } from '@/hooks';
import { connect } from 'umi';
import AuthComponent from '@/utils/auth/AuthComponent';
import { PostCard, SelectChannelOrder, SelectChannelStatus, DemandFieldUpdate } from './containers';
import { ChannelItem } from './components';
import { fetchChannelOutwards, getChannelPost } from '../service';
import { useChannelQuick, useChannelOnlineCheck, useChannelError } from '../hooks';

function List(props) {
    const { location } = props;
    const { query } = location;
    const { data: postData = {}, loading: postLoading, run: postRun } = useRequest(() =>
        getChannelPost(query.recruitCode)
    );
    const [loaded, setLoaded] = React.useState(false);
    const { data: channelData = {}, loading: channelLoading, run: fetchChannel } = useRequest(fetchChannelOutwards, {
        manual: true,
        onSuccess() {
            setLoaded(true);
        }
    });
    const [accountSelections, setAccountSelections] = React.useState({}); // 渠道下对应的账号
    const [selections, setSelections] = React.useState([]);
    const methods = useChannelQuick();

    // 仅检测所选账号是否在线
    const checkAccounts = React.useMemo(
        () =>
            selections.reduce(
                (prev, cur) => prev.concat({ channelCode: cur, channelAccountList: accountSelections[cur] }),
                []
            ),
        [selections, accountSelections]
    );

    const { check } = useChannelOnlineCheck({
        accountInfos: checkAccounts,
        channelCompanyCode: postData?.data?.companyCode
    });
    const [status, setStatus] = React.useState('0');
    const [order, setOrder] = React.useState('default');

    React.useEffect(() => {
        if (postData.data) {
            fetchChannel({ outwardId: postData?.data?.outwardId, searchStatus: status, orderByField: order });
        }
    }, [postData, status, order]);

    // 用于渠道分类渲染的数据结构
    const channelListData = React.useMemo(() => {
        const { data: dataSource = {} } = channelData;
        const {
            inwardChannelList = [],
            outwardChannelList = [],
            outChannelReleaseNum,
            totalOutwardNum,
            innerChannelReleaseNum,
            totalInwardNum
        } = dataSource;
        return [
            { title: '内部渠道', data: inwardChannelList, release: innerChannelReleaseNum, total: totalInwardNum },
            { title: '外部渠道', data: outwardChannelList, release: outChannelReleaseNum, total: totalOutwardNum }
        ];
    }, [channelData]);

    // 所有渠道组成的数组
    const [channelList, channelStatus] = React.useMemo(() => {
        const { data: dataSource = {} } = channelData;
        const { inwardChannelList = [], outwardChannelList = [] } = dataSource;
        const finalList = [...inwardChannelList, ...outwardChannelList];

        const finalStatus = finalList
            .filter(item => Number(item.channelStatus) === 1)
            .reduce((prev, { accountDetailVOList = [], releaseStatus }) => {
                const hasAccount = accountDetailVOList.length !== 0;
                const final = hasAccount ? accountDetailVOList.map(item => item.releaseStatus) : [releaseStatus];
                return [...prev, ...final];
            }, []);
        return [finalList, finalStatus];
    }, [channelData]);

    // 用于全选的渠道 code 数组
    const channelCodes = React.useMemo(() => {
        const { data: dataSource = {} } = channelData;
        const { inwardChannelList = [], outwardChannelList = [] } = dataSource;
        const inCodes = inwardChannelList.filter(item => item.channelStatus !== 0).map(item => item.channelCode);
        const outCodes = outwardChannelList
            .filter(item =>
                item.channelType === 3
                    ? item.channelStatus !== 0 && item.accountAuthVOList.length > 0
                    : item.channelStatus !== 0
            )
            .map(item => item.channelCode);
        return [...inCodes, ...outCodes];
    }, [channelData]);

    // 是否选中所有渠道
    const selectedAll = channelCodes.length === 0 ? false : channelCodes.every(code => selections.includes(code));

    // 选中渠道的消息信息
    const selectionItems = React.useMemo(() => channelList.filter(item => selections.includes(item.channelCode)), [
        channelList,
        selections
    ]);

    // 选中渠道的状态信息 (包括账号的信息)
    const selectionStatus = React.useMemo(() => {
        let finalStatus = [];
        selectionItems.forEach(item => {
            const account = accountSelections[item.channelCode].filter(_item => _item !== undefined) || [];
            if (account.length !== 0) {
                const finalAccountStatus = item.accountDetailVOList
                    .filter(_item => account.includes(_item.channelAccount))
                    .map(_item => _item.releaseStatus);
                finalStatus = finalStatus.concat(finalAccountStatus);
            } else {
                finalStatus.push(item.releaseStatus);
            }
        });
        return finalStatus;
    }, [selectionItems, accountSelections]);

    // 招聘渠道全控
    const handleSelectAll = () => {
        if (selectedAll) {
            setSelections([]);
        } else {
            setSelections(channelCodes);
        }
    };

    const handleStatus = value => {
        setSelections([]);
        setStatus(value);
    };

    const cardTitle = (
        <div>
            <Checkbox style={{ marginRight: 8 }} checked={selectedAll} onChange={handleSelectAll} />
            招聘渠道
            <span style={{ fontSize: 14, fontWeight: 400, paddingLeft: 16 }}>状态：</span>
            <SelectChannelStatus style={{ width: 120 }} onChange={handleStatus} />
            <span style={{ fontSize: 14, fontWeight: 400, paddingLeft: 16 }}>排序：</span>
            <SelectChannelOrder style={{ width: 140 }} onChange={setOrder} />
        </div>
    );

    const { checkError } = useChannelError();
    const sendRequest = async type => {
        const request = methods[type];
        if (request) {
            const channelAccountList = [];
            Object.entries(accountSelections)
                .filter(([key]) => selections.includes(key))
                .forEach(item => {
                    const [channelCode, channelAccount] = item;
                    channelAccountList.push({ channelCode, channelAccount });
                });

            const res = await request({
                channelCodeList: selections,
                recruitCode: query.recruitCode,
                channelAccountList
            });

            if (res.code === 10000) {
                const hasError = await checkError(res, { recruitCode: query.recruitCode });
                if (!hasError) {
                    message.success(res.msg || '操作成功');
                    fetchChannel({ outwardId: postData?.data?.outwardId, searchStatus: status, orderByField: order });
                }
            }
        }
    };

    const handlerMap = {
        release: type => {
            if (selectionStatus.length !== 0 && selectionStatus.every(item => item === 0)) {
                Modal.confirm({
                    title: '确定对所选渠道发布该招聘需求？',
                    okText: '确定',
                    cancelText: '取消',
                    onOk() {
                        sendRequest(type);
                    }
                });
            } else {
                message.warning('仅可操作未发布的渠道！');
            }
        },
        update: type => {
            if (!selectionStatus.some(item => item !== 1)) {
                Modal.confirm({
                    title: '确定对所选渠道更新该招聘需求？',
                    okText: '确定',
                    cancelText: '取消',
                    onOk() {
                        sendRequest(type);
                    }
                });
            } else {
                message.warning('仅可操作已发布的渠道！');
            }
        },
        online: type => {
            if (!selectionStatus.some(item => item !== 3)) {
                Modal.confirm({
                    title: '确定对所选渠道重新上线该招聘需求？',
                    okText: '确定',
                    cancelText: '取消',
                    onOk() {
                        sendRequest(type);
                    }
                });
            } else {
                message.warning('仅可操作已下线的渠道！');
            }
        },
        offline: type => {
            if (!selectionStatus.some(item => item !== 1)) {
                Modal.confirm({
                    title: '确定对所选渠道下线该招聘需求？',
                    okText: '确定',
                    cancelText: '取消',
                    onOk() {
                        sendRequest(type);
                    }
                });
            } else {
                message.warning('仅可操作已发布的渠道！');
            }
        }
    };

    const handlePublish = type => async () => {
        if (selections.length === 0 || accountSelections.length === 0) {
            message.warning('请至少选择一项发布渠道！');
            return;
        }
        if (
            selectionItems.some(item => {
                const value = accountSelections[item.channelCode].filter(_item => _item !== undefined);
                return item.channelType === 2 && (!value || value.length === 0);
            })
        ) {
            message.warning('招聘网站需至少选择一个账号！');
            return;
        }

        // 当选中选项里有招聘网站时，检测账号是否在线。
        if (selectionItems.some(item => item.channelType === 2)) {
            const checked = await check();

            if (!checked) {
                return;
            }

            handlerMap[type](type);
        } else {
            handlerMap[type](type);
        }
    };

    // 单个渠道的全控开关
    const changeSelections = code => {
        const finalSelection = [...selections];
        const index = selections.indexOf(code);
        if (index !== -1) {
            finalSelection.splice(index, 1);
        } else {
            finalSelection.push(code);
        }
        setSelections(finalSelection);
    };

    // 默认选中未发布的账号
    const defaultAccountSelectedRef = React.useRef(false);
    React.useEffect(() => {
        if (defaultAccountSelectedRef.current || channelList.length === 0) {
            return;
        }

        const defaultAccountSelections = channelList.reduce((prev, cur) => {
            let final = typeof prev === 'object' ? { ...prev } : {};

            const firstAccounts = cur?.accountDetailVOList[0] || {};
            const accounts = [firstAccounts.channelAccount];

            if (!final[cur.channelCode]) {
                final = { ...final, [cur.channelCode]: accounts };
            } else {
                final[cur.channelCode].concat(accounts);
            }
            return final;
        }, {});

        setAccountSelections(defaultAccountSelections);
        defaultAccountSelectedRef.current = true;
    }, [channelList]);

    // 默认选中未发布渠道
    const defaultSelectedRef = React.useRef(false);
    React.useEffect(() => {
        if (defaultSelectedRef.current || channelList.length === 0) {
            return;
        }
        const defaultSelections = channelList
            .filter(
                item =>
                    Number(item.releaseStatus) === 0 &&
                    Number(item.channelStatus) === 1 &&
                    item.accountDetailVOList.length !== 0
            )
            .map(item => item.channelCode);
        setSelections(defaultSelections);
        defaultSelectedRef.current = true;
    }, [channelList]);

    // 渠道选项与账户选项之间的关系

    const renderHeader = (item = {}) => {
        const { title = '内部渠道', data = [], total, release } = item;

        const codes = data
            .filter(_item =>
                _item.channelType === 3
                    ? _item.channelStatus !== 0 && _item.accountAuthVOList.length > 0
                    : _item.channelStatus !== 0
            )
            .map(_item => _item.channelCode);

        const checked = codes.length === 0 ? false : codes.every(code => selections.includes(code));
        const disabled = data.every(_item => _item.channelStatus === 0);

        // 内外渠道全控
        const handelChange = () => {
            let final = [];
            if (checked) {
                final = selections.filter(code => !codes.includes(code));
            } else {
                final = [...selections, ...codes];
            }
            setSelections(final);
        };

        return (
            <div style={{ display: 'flex' }}>
                <Checkbox
                    disabled={disabled}
                    checked={checked}
                    onChange={handelChange}
                    onClick={e => {
                        e.stopPropagation();
                    }}
                />
                <strong style={{ marginLeft: 8 }} level={4}>
                    {title}
                </strong>
                <Typography.Text style={{ marginLeft: 8 }} type="secondary">
                    发布情况：{`${release}/${total}`}
                </Typography.Text>
            </div>
        );
    };
    const getPath = channelType => {
        if (channelType === 3) {
            // 猎头
            return '/office/personnelManagement/recruitment/channel/hunter';
        }
        return '/office/personnelManagement/recruitment/channel/form';
    };

    const handleAccountChange = item => value => {
        setAccountSelections({ ...accountSelections, [item.channelCode]: value });
    };

    const renderItem = item => (
        <ChannelItem
            account={accountSelections[item.channelCode]}
            onAccountChange={handleAccountChange(item)}
            data={item}
            disabled={item.channelStatus === 0}
            checked={selections.includes(item.channelCode)}
            onChange={() => {
                changeSelections(item.channelCode);
            }}
            previewLink={{
                pathname: getPath(item.channelType),
                query: {
                    recruitId: query.recruitCode,
                    code: item.channelCode,
                    outwardId: postData?.data?.outwardId,
                    channelAccount: item?.accountDetailVOList[0]?.channelAccount
                }
            }}
            style={{ marginBottom: 16 }}
        />
    );

    const renderCategory = (data = []) => {
        let final = [];

        // 招聘网站
        const webs = data.filter(item => item.channelType === 2);
        // 猎头公司
        const companies = data.filter(item => item.channelType === 3);

        // 渲染内部渠道
        if (webs.length === 0 && companies.length === 0) {
            return data.map(_item => (
                <Col xs={24} md={12} xl={6} key={_item.channelCode}>
                    {renderItem(_item)}
                </Col>
            ));
        }

        // 渲染外部渠道
        if (webs.length !== 0) {
            final = [{ title: '招聘网站', data: webs }];
        }

        if (companies.length !== 0) {
            final = [...final, { title: '猎头公司', data: companies }];
        }

        return final.map(category => {
            const codes = category?.data
                ?.filter(item =>
                    item.channelType === 3
                        ? item.channelStatus !== 0 && item.accountAuthVOList.length > 0
                        : item.channelStatus !== 0
                )
                .map(item => item.channelCode);
            const disabled = category?.data?.every(item => item.channelStatus === 0);
            const checked = codes.length === 0 ? false : codes.every(item => selections.includes(item));
            let finalSelections = [...selections];

            // 招聘网站等多选功能
            const handleChange = () => {
                if (checked) {
                    finalSelections = finalSelections.filter(code => !codes.includes(code));
                } else {
                    finalSelections = [...finalSelections, ...codes];
                }
                setSelections(finalSelections);
            };

            return (
                <React.Fragment key={category.title}>
                    <Col span={24} style={{ marginBottom: 16 }}>
                        <Checkbox
                            disabled={disabled}
                            checked={checked}
                            onChange={handleChange}
                            style={{ marginRight: 8 }}
                        />
                        {category.title}
                    </Col>
                    {category.data.map(_item => (
                        <Col xs={24} md={12} xl={6} key={_item.channelCode}>
                            {renderItem(_item)}
                        </Col>
                    ))}
                </React.Fragment>
            );
        });
    };

    const renderList = () => {
        if (channelList.length === 0 && loaded) {
            return <Empty />;
        }

        return channelListData.map(item => {
            if (item?.data?.length === 0) {
                return null;
            }
            return (
                <Collapse
                    accordion
                    expandIconPosition="right"
                    defaultActiveKey="0"
                    style={{ marginBottom: 24 }}
                    key={item.title}
                >
                    <Collapse.Panel header={renderHeader(item)} key="0">
                        <Row gutter={16}>{renderCategory(item.data)}</Row>
                    </Collapse.Panel>
                </Collapse>
            );
        });
    };

    // 处理渠道操作按钮显示逻辑
    const [buttonsDisabled, setButtonsDisabled] = React.useState({
        online: false,
        offline: false,
        release: false,
        update: false
    });

    React.useEffect(() => {
        setButtonsDisabled({
            online: false,
            offline: false,
            release: false,
            update: false
        });
    }, [status]);

    React.useEffect(() => {
        if (channelStatus.length === 0) {
            return;
        }

        setButtonsDisabled({
            online: false,
            offline: false,
            release: false,
            update: false
        });

        // 所有账号对应渠道
        const isAllPublished = channelStatus.every(item => Number(item) === 1); // 都处于发布状态
        const isAllUnPublished = channelStatus.every(item => Number(item) === 0); // 都处于未发布状态
        const isAllChecking = channelStatus.every(item => Number(item) === 2); // 都处于审核中
        const isAllOffline = channelStatus.every(item => Number(item) === 3); // 都处于下线状态

        if (isAllPublished) {
            setButtonsDisabled({ online: true, offline: false, update: false, release: true });
        }

        if (isAllUnPublished) {
            setButtonsDisabled({ online: true, offline: true, update: true, release: false });
        }

        if (isAllChecking) {
            setButtonsDisabled({ online: true, offline: true, update: true, release: true });
        }

        if (isAllOffline) {
            setButtonsDisabled({ online: false, offline: true, update: true, release: true });
        }
    }, [channelStatus]);

    const extra = (
        <div style={{ display: 'flex', alignItems: 'center' }}>
            <AuthComponent code="office:recruitment:channel:statistics">
                <Button
                    onClick={() => {
                        history.push(
                            `/office/personnelManagement/recruitment/channel/history/list?recruitCode=${
                                query.recruitCode
                            }&channelCompanyCode=${postData?.data?.companyCode || ''}`
                        );
                    }}
                >
                    查看记录
                </Button>
            </AuthComponent>

            {!buttonsDisabled.online && (
                <AuthComponent code="office:recruitment:channel:online">
                    <Button style={{ marginLeft: 8 }} onClick={handlePublish('online')}>
                        上线
                    </Button>
                </AuthComponent>
            )}

            {!buttonsDisabled.offline && (
                <AuthComponent code="office:recruitment:channel:offline">
                    <Button style={{ marginLeft: 8 }} onClick={handlePublish('offline')}>
                        下线
                    </Button>
                </AuthComponent>
            )}

            {!buttonsDisabled.update && (
                <AuthComponent code="office:recruitment:channel:publish:edit">
                    <Button style={{ marginLeft: 8 }} onClick={handlePublish('update')}>
                        更新
                    </Button>
                </AuthComponent>
            )}

            {!buttonsDisabled.release && (
                <AuthComponent code="office:recruitment:channel:publish">
                    <Button type="primary" onClick={handlePublish('release')} style={{ marginLeft: 8 }}>
                        一键发布
                    </Button>
                </AuthComponent>
            )}
        </div>
    );

    return (
        <>
            <DemandFieldUpdate
                style={{ margin: 16, marginBottom: 0 }}
                onRefresh={postRun}
                outwardId={postData?.data?.outwardId}
            />
            <PostCard data={postData?.data} loading={postLoading} />
            <Card
                title={cardTitle}
                bordered={false}
                loading={channelLoading}
                bodyStyle={{ padding: 24 }}
                style={{ margin: 16 }}
                extra={loaded ? extra : null}
            >
                {renderList()}
            </Card>
        </>
    );
}

export default connect()(List);
